home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.31-14 / scripts / conmakehash.c < prev    next >
C/C++ Source or Header  |  2009-09-09  |  6KB  |  294 lines

  1. /*
  2.  * conmakehash.c
  3.  *
  4.  * Create arrays for initializing the kernel folded tables (using a hash
  5.  * table turned out to be to limiting...)  Unfortunately we can't simply
  6.  * preinitialize the tables at compile time since kfree() cannot accept
  7.  * memory not allocated by kmalloc(), and doing our own memory management
  8.  * just for this seems like massive overkill.
  9.  *
  10.  * Copyright (C) 1995-1997 H. Peter Anvin
  11.  *
  12.  * This program is a part of the Linux kernel, and may be freely
  13.  * copied under the terms of the GNU General Public License (GPL),
  14.  * version 2, or at your option any later version.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <sysexits.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22.  
  23. #define MAX_FONTLEN 256
  24.  
  25. typedef unsigned short unicode;
  26.  
  27. void usage(char *argv0)
  28. {
  29.   fprintf(stderr, "Usage: \n"
  30.          "        %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
  31.   exit(EX_USAGE);
  32. }
  33.  
  34. int getunicode(char **p0)
  35. {
  36.   char *p = *p0;
  37.  
  38.   while (*p == ' ' || *p == '\t')
  39.     p++;
  40.   if (*p != 'U' || p[1] != '+' ||
  41.       !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
  42.       !isxdigit(p[5]) || isxdigit(p[6]))
  43.     return -1;
  44.   *p0 = p+6;
  45.   return strtol(p+2,0,16);
  46. }
  47.  
  48. unicode unitable[MAX_FONTLEN][255];
  49.                 /* Massive overkill, but who cares? */
  50. int unicount[MAX_FONTLEN];
  51.  
  52. void addpair(int fp, int un)
  53. {
  54.   int i;
  55.  
  56.   if ( un <= 0xfffe )
  57.     {
  58.       /* Check it isn't a duplicate */
  59.  
  60.       for ( i = 0 ; i < unicount[fp] ; i++ )
  61.     if ( unitable[fp][i] == un )
  62.       return;
  63.  
  64.       /* Add to list */
  65.  
  66.       if ( unicount[fp] > 254 )
  67.     {
  68.       fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
  69.       exit(EX_DATAERR);
  70.     }
  71.  
  72.       unitable[fp][unicount[fp]] = un;
  73.       unicount[fp]++;
  74.     }
  75.  
  76.   /* otherwise: ignore */
  77. }
  78.  
  79. int main(int argc, char *argv[])
  80. {
  81.   FILE *ctbl;
  82.   char *tblname;
  83.   char buffer[65536];
  84.   int fontlen;
  85.   int i, nuni, nent;
  86.   int fp0, fp1, un0, un1;
  87.   char *p, *p1;
  88.  
  89.   if ( argc < 2 || argc > 5 )
  90.     usage(argv[0]);
  91.  
  92.   if ( !strcmp(argv[1],"-") )
  93.     {
  94.       ctbl = stdin;
  95.       tblname = "stdin";
  96.     }
  97.   else
  98.     {
  99.       ctbl = fopen(tblname = argv[1], "r");
  100.       if ( !ctbl )
  101.     {
  102.       perror(tblname);
  103.       exit(EX_NOINPUT);
  104.     }
  105.     }
  106.  
  107.   /* For now we assume the default font is always 256 characters. */    
  108.   fontlen = 256;
  109.  
  110.   /* Initialize table */
  111.  
  112.   for ( i = 0 ; i < fontlen ; i++ )
  113.     unicount[i] = 0;
  114.  
  115.   /* Now we come to the tricky part.  Parse the input table. */
  116.  
  117.   while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
  118.     {
  119.       if ( (p = strchr(buffer, '\n')) != NULL )
  120.     *p = '\0';
  121.       else
  122.     fprintf(stderr, "%s: Warning: line too long\n", tblname);
  123.  
  124.       p = buffer;
  125.  
  126. /*
  127.  * Syntax accepted:
  128.  *    <fontpos>    <unicode> <unicode> ...
  129.  *    <range>        idem
  130.  *    <range>        <unicode range>
  131.  *
  132.  * where <range> ::= <fontpos>-<fontpos>
  133.  * and <unicode> ::= U+<h><h><h><h>
  134.  * and <h> ::= <hexadecimal digit>
  135.  */
  136.  
  137.       while (*p == ' ' || *p == '\t')
  138.     p++;
  139.       if (!*p || *p == '#')
  140.     continue;    /* skip comment or blank line */
  141.  
  142.       fp0 = strtol(p, &p1, 0);
  143.       if (p1 == p)
  144.     {
  145.       fprintf(stderr, "Bad input line: %s\n", buffer);
  146.       exit(EX_DATAERR);
  147.         }
  148.       p = p1;
  149.  
  150.       while (*p == ' ' || *p == '\t')
  151.     p++;
  152.       if (*p == '-')
  153.     {
  154.       p++;
  155.       fp1 = strtol(p, &p1, 0);
  156.       if (p1 == p)
  157.         {
  158.           fprintf(stderr, "Bad input line: %s\n", buffer);
  159.           exit(EX_DATAERR);
  160.         }
  161.       p = p1;
  162.         }
  163.       else
  164.     fp1 = 0;
  165.  
  166.       if ( fp0 < 0 || fp0 >= fontlen )
  167.     {
  168.         fprintf(stderr,
  169.             "%s: Glyph number (0x%x) larger than font length\n",
  170.             tblname, fp0);
  171.         exit(EX_DATAERR);
  172.     }
  173.       if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
  174.     {
  175.         fprintf(stderr,
  176.             "%s: Bad end of range (0x%x)\n",
  177.             tblname, fp1);
  178.         exit(EX_DATAERR);
  179.     }
  180.  
  181.       if (fp1)
  182.     {
  183.       /* we have a range; expect the word "idem" or a Unicode range of the
  184.          same length */
  185.       while (*p == ' ' || *p == '\t')
  186.         p++;
  187.       if (!strncmp(p, "idem", 4))
  188.         {
  189.           for (i=fp0; i<=fp1; i++)
  190.         addpair(i,i);
  191.           p += 4;
  192.         }
  193.       else
  194.         {
  195.           un0 = getunicode(&p);
  196.           while (*p == ' ' || *p == '\t')
  197.         p++;
  198.           if (*p != '-')
  199.         {
  200.           fprintf(stderr,
  201. "%s: Corresponding to a range of font positions, there should be a Unicode range\n",
  202.               tblname);
  203.           exit(EX_DATAERR);
  204.             }
  205.           p++;
  206.           un1 = getunicode(&p);
  207.           if (un0 < 0 || un1 < 0)
  208.         {
  209.           fprintf(stderr,
  210. "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
  211.               tblname, fp0, fp1);
  212.           exit(EX_DATAERR);
  213.             }
  214.           if (un1 - un0 != fp1 - fp0)
  215.         {
  216.           fprintf(stderr,
  217. "%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
  218.               tblname, un0, un1, fp0, fp1);
  219.           exit(EX_DATAERR);
  220.             }
  221.           for(i=fp0; i<=fp1; i++)
  222.         addpair(i,un0-fp0+i);
  223.         }
  224.         }
  225.       else
  226.     {
  227.         /* no range; expect a list of unicode values for a single font position */
  228.  
  229.         while ( (un0 = getunicode(&p)) >= 0 )
  230.           addpair(fp0, un0);
  231.     }
  232.       while (*p == ' ' || *p == '\t')
  233.     p++;
  234.       if (*p && *p != '#')
  235.     fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
  236.     }
  237.  
  238.   /* Okay, we hit EOF, now output hash table */
  239.   
  240.   fclose(ctbl);
  241.   
  242.  
  243.   /* Compute total size of Unicode list */
  244.   nuni = 0;
  245.   for ( i = 0 ; i < fontlen ; i++ )
  246.     nuni += unicount[i];
  247.   
  248.   printf("\
  249. /*\n\
  250.  * Do not edit this file; it was automatically generated by\n\
  251.  *\n\
  252.  * conmakehash %s > [this file]\n\
  253.  *\n\
  254.  */\n\
  255. \n\
  256. #include <linux/types.h>\n\
  257. \n\
  258. u8 dfont_unicount[%d] = \n\
  259. {\n\t", argv[1], fontlen);
  260.  
  261.   for ( i = 0 ; i < fontlen ; i++ )
  262.     {
  263.       printf("%3d", unicount[i]);
  264.       if ( i == fontlen-1 )
  265.         printf("\n};\n");
  266.       else if ( i % 8 == 7 )
  267.         printf(",\n\t");
  268.       else
  269.         printf(", ");
  270.     }
  271.   
  272.   printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
  273.   
  274.   fp0 = 0;
  275.   nent = 0;
  276.   for ( i = 0 ; i < nuni ; i++ )
  277.     {
  278.       while ( nent >= unicount[fp0] )
  279.     {
  280.       fp0++;
  281.       nent = 0;
  282.     }
  283.       printf("0x%04x", unitable[fp0][nent++]);
  284.       if ( i == nuni-1 )
  285.          printf("\n};\n");
  286.        else if ( i % 8 == 7 )
  287.          printf(",\n\t");
  288.        else
  289.          printf(", ");
  290.     }
  291.  
  292.   exit(EX_OK);
  293. }
  294.